package org.tinygame.herostory;

import com.google.protobuf.GeneratedMessageV3;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinygame.herostory.cmdhandler.CmdHandlerFactory;
import org.tinygame.herostory.cmdhandler.ICmdHandler;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author anan
 * @create 2022-05-04 16:16
 */
public class MainThreadProcessor {
    /**
     * 日志对象
     */
    static private final Logger LOGGER = LoggerFactory.getLogger(MainThreadProcessor.class);

    /**
     * 单例对象
     */
    static private final MainThreadProcessor _instance = new MainThreadProcessor();

    /**
     * 创建一个单线程的线程池
     */
    private final ExecutorService _es = Executors.newSingleThreadExecutor(newRunnable -> {
        Thread newThread = new Thread(newRunnable);
        newThread.setName("MainThreadProcessor");
        return newThread;
    });

    private MainThreadProcessor(){}

    /**
     * 获取单例对象
     * @return
     */
    static public MainThreadProcessor getInstance(){ return _instance; }


    /**
     * 处理消息
     * @param ctx
     * @param msg
     */
    public void process(ChannelHandlerContext ctx, Object msg){
        if (null == ctx ||
                null == msg) {
            return;
        }
        final Class<?> msgClazz = msg.getClass();

        LOGGER.info(
                "收到客户端消息, msgClazz = {}, msgBody = {}",
                msgClazz.getSimpleName(),
                msg
        );

        _es.submit(() ->{
            try {
                ICmdHandler<? extends GeneratedMessageV3> cmdHandler = CmdHandlerFactory.create(msg.getClass());

                if (null != cmdHandler) {
                    cmdHandler.handle(ctx, cast(msg));
                }
            } catch (Exception ex) {
                // 记录错误日志
                LOGGER.error(ex.getMessage(), ex);
            }
        });
    }

    static private <TCmd extends GeneratedMessageV3> TCmd cast(Object msg) {
        if (!(msg instanceof GeneratedMessageV3)) return null;
        else {
            return (TCmd) msg;
        }
    }

    public void process(Runnable r){
        if(null != r){
            _es.submit(r);
        }
    }




}
